home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
p063b9s.zip
/
UNIT
/
NLCOMP.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-06-25
|
66KB
|
1,545 lines
UNIT NLComp;
{╔══════════════════════════════════════════════════════════════════════════╗}
{║ Nodeliste compiler Last changed: 25.06.96 SA ║}
{║ ║}
{║ (C) Copyright 1989-96 by ║}
{║ Dan Wulff, Jens Sandalgaard, Steen Christensen & S¢ren Ager ║}
{║ And special guest star: Birger Kristensen ║}
{║ ║}
{║ This source may not be given to anybody, without the written permission ║}
{║ from The Portal Team. ║}
{╚══════════════════════════════════════════════════════════════════════════╝}
{$I POPDEFS.INC}
INTERFACE
USES Use32;
PROCEDURE CompileNodeList(Forced: Boolean);
IMPLEMENTATION
USES OpCrt, OpDos, OpString, OpWindow, OpRoot, OpLArray,
Util, Globals, Dos, NodeList, FileUtil, OproUtil, StrUtil, Com,
Keyboard, InterCom, LogFile, NetFile, Crc, MTask, ArcView, PoPTypes,
MailUtil, Display, FuncSrvr, BTree, AreaMisc
{ indsat BK'94 },OPUS_173{ indsat BK'94 };
TYPE { indsat BK'94 }
CtlBlock = RECORD
ControlBlockSize : WORD; { Blocksize of Index Blocks }
ControlRoot, { Block number of Root }
ControlHiBlock, { Block number of last block }
ControlLowLeaf : LONGINT; { Block number of first leaf }
ControlHighLeaf : LONGINT; { Block number of last leaf }
ControlFree : LONGINT; { Head of freelist }
ControlLevels : WORD; { Number of index levels }
ControlParity : WORD; { XOR of above fields }
END;
INodeBlk = RECORD
IndexFirst : LONGINT; { Pointer to next lower level }
IndexBLink : LONGINT; { Pointer to previous link }
IndexFLink : LONGINT; { Pointer to next link }
IndexCount : INTEGER; { Count of Items in block }
IndexStr : WORD; { Offset in block of 1st str }
{If IndxFirst is NOT -1, this is INode:}
IndexRef : ARRAY[0..49] OF
RECORD
IndexOfs : WORD; { Offset of string into block }
IndexLen : WORD; { Length of string }
IndexData : LONGINT; { Record number of string }
IndexPtr : LONGINT; { Block number of lower index }
END;
END;
LNodeBlk = RECORD
IndexFirst : LONGINT; { Pointer to next lower level }
IndexBLink : LONGINT; { Pointer to previous link }
IndexFLink : LONGINT; { Pointer to next link }
IndexCount : INTEGER; { Count of Items in block }
IndexStr : WORD; { Offset in block of 1st str }
LeafRef : ARRAY [0..49] OF
RECORD
KeyOfs : WORD; { Offset of string into block }
KeyLen : WORD; { Length of string }
KeyVal : LONGINT; { Pointer to data block }
END;
END;
bigleaf = RECORD
IndexFirst : LONGINT; { Pointer to next lower level }
IndexBLink : LONGINT; { Pointer to previous link }
IndexFLink : LONGINT; { Pointer to next link }
IndexCount : INTEGER; { Count of Items in block }
IndexStr : WORD; { Offset in block of 1st str }
LeafRef : ARRAY [0..50] OF
RECORD
KeyOfs : WORD; { Offset of string into block }
KeyLen : WORD; { Length of string }
KeyVal : LONGINT; { Pointer to data block }
END;
END;
bigindex = RECORD
IndexFirst : LONGINT; { Pointer to next lower level }
IndexBLink : LONGINT; { Pointer to previous link }
IndexFLink : LONGINT; { Pointer to next link }
IndexCount : INTEGER; { Count of Items in block }
IndexStr : WORD; { Offset in block of 1st str }
{If IndxFirst is NOT -1, this is INode:}
IndexRef : ARRAY [0..50] OF
RECORD
IndexOfs : WORD; { Offset of string into block }
IndexLen : WORD; { Length of string }
IndexData : LONGINT; { Record number of string }
IndexPtr : LONGINT; { Block number of lower index }
END;
END; { indsat bk'94 }
PROCEDURE CompileNodeList(Forced: Boolean);
VAR
FidoUser,v7 : OpArray;
Temp : WindowPtr;
FoundOne : Boolean;
FidoUserNum,
normcost : WORD;
Test,num,numcost:INTEGER;
sr:SearchRec;
HostPhone:S40;
s,oldnlname:STRING;
RE:NodeExtra;
NodeListSegRec : TNodeListSeg;
NodeListSegFile : TNetFile;
FUNCTION FindOldNlName(VAR OldNlName: String; VAR Num: Integer): Boolean;
VAR
Test, MaxNum : Integer;
Sr : SearchRec;
BEGIN
MaxNum:=-1;
OldNLName:='';
FindFirst(Cfg.NodeList+NodeListSegRec.NodeListName+'.*', AnyFile, sr);
WHILE DOSError=0 DO
BEGIN
Val(Copy(Sr.Name, Pos('.', Sr.Name)+1,3), Num, Test);
IF (Test=0) AND (Num>MaxNum) THEN
BEGIN
MaxNum:=Num;
OldNLName:=Cfg.NodeList+Sr.Name;
END;
FindNext(sr);
END;
FindClose(sr);
Num:=MaxNum;
FindOldNlName:=(OldNlName<>'');
END;
FUNCTION ProcessNodeDiff: Boolean;
LABEL
LookForMore;
VAR
Found, GoodCRC : Boolean;
Sr : SearchRec;
BufSize : LONGINT;
numofdays, x, newnum : Integer;
BadName, PackedDiff,
DiffName, OldDir, s : String;
Ind, Ud, NodeDiff : TBufTextFile;
i, y,
m, d, dofw : Word;
Ch : Char;
FUNCTION GoodNLCRC:BOOLEAN;
VAR
f:BufIdStream;
s:STRING;
BufSize:LONGINT;
CrcOk,Crc16:WORD;
i:INTEGER;
ch:CHAR;
BEGIN
BufSize:=Max64k(MaxAvail-1024);
f.Init(Cfg.Nodelist+'PORTAL.$$$', SOpenRead, BufSize);
s:='';
REPEAT
f.Read(ch,1);
IF (ch<>#10) AND (ch<>#13) THEN s:=s+ch;
UNTIL ch=#10;
i:=Length(s);
WHILE (s[i]>='0') AND (s[i]<='9') DO
Dec(i);
Val(Copy(s,i+1,5), CrcOk, i);
Crc16:=0;
WHILE f.IdStatus=0 DO
BEGIN
f.Read(ch,1);
IF f.IdStatus=0 THEN Crc16:=UpdCrc16(Byte(ch),Crc16);
END;
f.Done;
Crc16:=UpdCrc16(0,Crc16);
Crc16:=UpdCrc16(0,Crc16);
GoodNLCRC:=(CrcOk=Crc16);
END;
PROCEDURE AddToFilesBBS(NewName, OldName: S12);
VAR
FilesBBS,
NewFilesBBS : PBufTextFile;
Line, s : String;
BEGIN
WriteLn('Adding new nodelist to FILES.BBS');
Line:=CPad(NewName, 13)+NodeListSegRec.NewNLDesc;
IF Cfg.AreaMan.InsDLCnt THEN AddDlC(Line);
New(FilesBBS, InitCreate(AddBackSlash(NodeListSegRec.NewNLPath)+'FILES.BBS', SOpen+ShareDenyNone, 2048));
IF FilesBBS=NIL THEN
BEGIN
WriteLn('Can''t update '+AddBackSlash(NodeListSegRec.NewNLPath)+'FILES.BBS with description: '+Line);
END ELSE
BEGIN
New(NewFilesBBS, Init(AddBackSlash(NodeListSegRec.NewNLPath)+'NLC-TMP.$$$', SCreate, 2048));
IF NewFilesBBS=NIL THEN
BEGIN
FilesBBS^.WriteLn(Line);
Dispose(FilesBBS, Done);
END ELSE
BEGIN
FilesBBS^.SetPos(0, PosAbs);
Found:=False;
WHILE NOT FilesBBS^.EoF AND (NewFilesBBS^.GetStatus=0) DO
BEGIN
FilesBBS^.ReadLn(s);
IF (Pos(' ',s)>0) AND (StUpCase(Copy(s,1,Pos(' ',s)-1))=OldName) THEN
BEGIN
Found:=True;
{ IF Cfg.AreaMan.InsDLCnt THEN IncDLC(Line, GetDLC(s));}
NewFilesBBS^.WriteLn(Line);
END ELSE
NewFilesBBS^.WriteLn(s);
END;
IF Not Found THEN NewFilesBBS^.WriteLn(Line);
IF NewFilesBBS^.GetStatus<>0 THEN
BEGIN
AddLog('!', 'Can''t update FILES.BBS with description: '+Line);
Dispose(FilesBBS, Done); Dispose(NewFilesBBS, Done);
DeleteFile(AddBackSlash(NodeListSegRec.NewNLPath)+'NLC-TMP.$$$');
END ELSE
BEGIN
IF Found THEN
BEGIN
IF DeleteFile(AddBackSlash(NodeListSegRec.NewNLPath)+OldName) THEN
AddLog(':', 'Erasing '+OldName+' replaced by '+NewName);
END;
Dispose(FilesBBS, Done); Dispose(NewFilesBBS, Done);
DeleteFile(AddBackSlash(NodeListSegRec.NewNLPath)+'FILES.BBS');
RenameFile(AddBackSlash(NodeListSegRec.NewNLPath)+'NLC-TMP.$$$',
AddBackSlash(NodeListSegRec.NewNLPath)+'FILES.BBS');
END;
END;
END;
END;
BEGIN
Found:=False;
WriteLn('Looking for '+NodeListSegRec.DiffFileName+'''s');
LookForMore:
newnum:=num+7;
GetDate(y,m,d,dofw);
Dec(y);
IF (y MOD 4=0) AND (y MOD 100<>0) THEN numofdays:=366 ELSE numofdays:=365;
IF newnum>numofdays THEN newnum:=newnum-numofdays;
s:=Cfg.Nodelist+NodeListSegRec.DiffFileName+'.'+LongIntForm('@@@',newnum);
diffname:=s;
s[Length(s)-2]:='?';
FindFirst(s,AnyFile,sr);
WHILE (DosError=0) And Not (sr.Name[Length(Sr.name)-2] IN ['A'..'Z']) DO
FindNext(Sr);
IF DOSError=0 THEN
BEGIN
Found:=True;
GetDir(0,olddir);
ChangeDir(Cfg.Nodelist);
WriteLn('Unpacking '+sr.name);
ArcCommand(ArcType(sr.Name),2,sr.name,'*.0?? *.1?? *.2?? *.3??');
packeddiff:=Cfg.Nodelist+sr.name;
Changedir(olddir);
END ELSE
PackedDiff:='';
FindClose(Sr);
IF ExistFile(DiffName) THEN
BEGIN
WriteLn('Updating nodelist with '+JustFileName(DiffName));
BufSize:=Max64k((MaxAvail-1024) DIV 5);
IF BufSize>32760 THEN BufSize:=32760;
Ind.Init(OldNLName, SOpenRead, BufSize*2);
Ud.Init(Cfg.Nodelist+'PORTAL.$$$', SCreate, BufSize*2);
NodeDiff.Init(DiffName, SOpenRead, BufSize);
WHILE NOT NodeDiff.EoF DO
BEGIN
NodeDiff.ReadLn(s);
IF (s<>'') AND (s[1] IN ['A','C','D']) THEN
BEGIN
Val(Copy(s,2,255),x,test);
CASE s[1] OF
'A' : FOR i:=1 TO x DO
BEGIN
NodeDiff.ReadLn(s);
Ud.WriteLn(s);
END;
'C' : FOR i:=1 TO x DO
BEGIN
Ind.ReadLn(s);
Ud.WriteLn(s);
END;
'D' : FOR i:=1 TO x DO
Ind.ReadLn(s);
END;
END;
END;
NodeDiff.Done;
Ind.Done;
{ Ch:=#26;
Ud.Write(Ch, 1);}
Ud.Done;
IF NodeListSegRec.CheckCRC THEN
BEGIN
WriteLn('Calculating CRC');
GoodCrc:=GoodNLCRC;
END ELSE GoodCrc:=TRUE;
IF DeleteFile(DiffName) THEN WriteLn('Erasing '+JustFileName(diffname));
IF NOT GoodCRC THEN
BEGIN
WriteLn('CRC Error on update');
BadName:=UniqueName(ForceExtension(PackedDiff,'BAD'));
AddLog('!','CRC Error in nodelist '+JustFileName(diffname)+' renamed to '+JustFileName(BadName));
DeleteFile(Cfg.NodeList+'PORTAL.$$$');
RenameFile(PackedDiff,BadName);
ProcessNodeDiff:=False;
Exit;
END;
IF DeleteFile(packeddiff) THEN WriteLn('Erasing '+JustFileName(packeddiff));
END;
IF ExistFile(Cfg.NodeList+'PORTAL.$$$') THEN
BEGIN
s:=Cfg.Nodelist+NodeListSegRec.NodeListName+'.'+LongIntForm('@@@',newnum);
IF RenameFile(cfg.nodelist+'PORTAL.$$$',s) THEN
BEGIN
IF DeleteFile(oldnlname) THEN oldnlname:=s;
IF NodeListSegRec.NewNLPath<>'' THEN
BEGIN
WriteLn('Packing new nodelist');
ChangeDir(JustPathName(Cfg.Nodelist));
ArcCommand(1,1,AddBackSlash(NodeListSegRec.NewNLPath)+NodeListSegRec.NodeListName+
'.A'+LongIntForm('@@',newnum MOD 100),
NodeListSegRec.NodeListName+'.'+LongIntForm('@@@',newnum));
ChangeDir(StartPath);
AddToFilesBBS(NodeListSegRec.NodeListName+'.A'+LongIntForm('@@', NewNum MOD 100),
NodeListSegRec.NodeListName+'.A'+LongIntForm('@@', Num MOD 100));
END;
END;
num:=newnum;
GOTO LookForMore;
END;
ProcessNodeDiff:=Found;
END;
PROCEDURE ProcessNodeList;
TYPE
tblock = array[0..511] of char; { indsat BK'94 }
VAR
DoingService,First,FirstRec : Boolean;
FidoUserLst,f : TBufTextFile;
FidoBuf,
i, OldZone : INTEGER;
nettitle,
oldnettitle,
keyword,ss : STRING;
MaxBufSize : LongInt;
f1,f2 : BufIdStream;
QNLI : QBBSNodeIdxRecord;
V6 : NewNodeList;
V6I : NewNodeListIndex;
FidoArraySize,
OldSLength,
CurNLPos,Use : LongInt;
FileNum : BYTE;
CurAdr : TFidoAddress;
InclTab,ExclTab: SendToTabType;
currentplace_in_ndx : longint; { indsat BK'94 }
instring : s160; { indsat BK'94 }
inlength,v7num : word; { indsat BK'94 }
conblock : tblock; { indsat BK'94 }
controlblock : ctlblock absolute conblock ; { indsat BK'94 }
tempblock : tblock;
PROCEDURE AddFileNum(CONST s: S12; First: Boolean);
VAR
f : FILE OF NodeExtra;
sr : SearchRec;
BEGIN
Assign(f, Cfg.NodeList+ListExtension('NODEINC.'));
FileMode:=ShareWrite+ShareDenyRW;
Reset(f);
IF (IOResult<>0) OR (First) THEN ReWrite(f) ELSE Seek(f,FileSize(f));
Inc(FileNum);
FindFirst(Cfg.NodeList+s,Archive,sr);
FindClose(sr);
RE.name:=s;
RE.time:=sr.time;
Write(f,RE);
Close(f);
END;
PROCEDURE ProcessNodeListLine(s: STRING);
TYPE
tblock = array[0..511] of char; { indsat BK'94 }
VAR
IsZone,IsHost,
IsHub,IsDown,
IsPvt,IsHold,
IsCrash,IsPoint,
IsRegion : BOOLEAN;
BossPhone,
OurPhonenumber : S40;
OurSysOp,
OurMiscInfo,
OurSystemName : S60;
OurCost,
CurBaudRate : WORD;
OurModemType : Byte;
Ch : CHAR;
i : Integer;
block : tblock; { indsat BK'94 }
leafblock : LNodeBlk ABSOLUTE block; { indsat BK'94 }
PROCEDURE QBBSNode;
VAR
QI : QBBSNodeIdxRecord;
BEGIN
FillChar(QI,SizeOf(QI),0);
QI.RawFile:=FileNum;
IF IsZone THEN
BEGIN
QI.Number:=CurAdr.Zone;
QI.NodeType:=ntZone;
END ELSE
BEGIN
QI.Number:=CurAdr.Net;
IF IsRegion THEN QI.NodeType:=ntRegion ELSE QI.NodeType:=ntNet;
END;
QI.RawPos:=CurNLPos;
QI.Cost:=OurCost;
f2.Write(QI, SizeOf(QI));
END;
PROCEDURE NewNode;
BEGIN
FillChar(V6,SizeOf(V6),0);
WITH V6 DO
BEGIN
IF CurAdr.Zone=OldZone THEN
BEGIN
NetNumber:=CurAdr.Net;
NodeNumber:=CurAdr.Node;
END ELSE
BEGIN
NodeNumber:=-2;
NetNumber:=CurAdr.Zone;
OldZone:=CurAdr.Zone;
END;
IF IsPoint THEN HubNode:=CurAdr.Point;
Str2AsciiZ(OurSystemName,SystemName,34);
Str2AsciiZ(OurMiscInfo,MiscInfo,30);
cost:=OurCost;
realcost:=cost;
Str2AsciiZ(OurPhoneNumber,PhoneNumber,40);
baudrate:=CurBaudRate DIV 300;
IF IsPoint THEN
BEGIN
V6I.Net:=-1;
V6I.Node:=CurAdr.Point;
END ELSE
BEGIN
V6I.Net:=NetNumber;
V6I.Node:=NodeNumber;
END;
IF IsHost THEN nodeflags:=nodeflags OR 2 ELSE
IF IsHub THEN nodeflags:=nodeflags OR 1 ELSE
IF IsRegion THEN
BEGIN
nodeflags:=nodeflags OR 4;
V6I.Node:=-1;
END;
IF IsCrash THEN nodeflags:=nodeflags OR 16;
IF IsPoint THEN NodeFlags:=NodeFlags Or 4096;
ModemType:=OurModemType;
END;
f1.Write(V6, SizeOf(V6));
f2.Write(V6I, SizeOf(V6I));
END;
PROCEDURE V7Node;
Type
RNode_op_IndexRef = RECORD
IndexLen : byte; { Length of string }
IndexData : LONGINT; { Record number of string }
IndexPtr : LONGINT; { Block number of lower index }
Node : STRING [8]; { String to save Nodenumber }
END;
tblock = ARRAY [0..511] OF CHAR;
bblock = ARRAY [0..1023] OF CHAR;
nblock = ARRAY [0..511] OF CHAR;
Stackarray = ARRAY [1..30] OF LONGINT;
VAR
realdat : realdatrec;
packline : s160;
addressline : s160;
FUNCTION CompAddress (VAR ALine, Desire; L,F : CHAR) : INTEGER;
VAR
Key : tfidoaddress ABSOLUTE ALine;
Desired : tfidoaddress ABSOLUTE Desire;
Count : BYTE;
K : INTEGER;
BEGIN
Count := 0;
k := 0;
REPEAT
INC (Count);
CASE Count OF
1 : BEGIN
IF (f > #0) THEN
if ( l > #0) then
K := Key.zone - Desired.zone
else k := k - desired.zone
else if ( l > #0 ) then k := desired.zone;
END;
2 : BEGIN
IF (f > #2) THEN
if ( l > #2) then
K := Key.net - Desired.net
else k := k - desired.net
else if (l > #2) then k := desired.net;
END;
3 : BEGIN
IF (f > #4) THEN
if (l > #4) then
K := Key.node - Desired.node
else k := k - desired.node
else if (l > #4) then k := desired.node;
END;
4 : BEGIN
IF (f > #6) THEN
if (l > #6) then
K := Key.point - Desired.point
else k := k - desired.point
else if (l > #6) then k := desired.point;
END;
END; { Case }
UNTIL (Count = 4) OR (K <> 0);
CompAddress := K;
END;
function MakeAddress (Z, Nt, N, P : Word) : S160;
type
NodeType = record { A node address type }
Len : Byte;
Zone : Word;
Net : Word;
Node : Word;
Point : Word;
end;
var
Address : NodeType;
S2 : S160 absolute Address;
begin
With Address do
begin
Zone := Z;
Net := Nt;
Node := N;
Point := P;
end;
address.len := 8;
with address do
begin
if p = 0 then len:=6;
if n = 0 then len:=6; { original := 4}
if nt = 0 then len:=2;
if z = 0 then len:=0;
end;
MakeAddress := S2;
end;
PROCEDURE read_block (VAR ver : OpArray; VAR rblock : tblock; number : INTEGER);
BEGIN
ver.reta(number,0,rblock);
END;
PROCEDURE write_block (VAR ver : OpArray; VAR rblock : tblock; number : INTEGER);
BEGIN
ver.seta(number,0,rblock);
END;
function insert_btree(VAR ver : OpArray; incoming : s160) : boolean;
VAR
block : tblock;
indexblock : INodeBlk ABSOLUTE block;
leafblock : LNodeBlk ABSOLUTE block;
newblock : tblock;
newindexblock : INodeBlk ABSOLUTE newblock;
newleafblock : LNodeBlk ABSOLUTE newblock;
bigblock : bblock;
bigindexblock : bigindex ABSOLUTE bigblock;
bigleafblock : bigleaf ABSOLUTE bigblock;
Stack_up_count,
NOde_up_KeyVal,
Count,
tempcounter : byte;
difference : INTEGER;
currentblocknumber : LONGINT;
Stack_up : Stackarray;
Finish : BOOLEAN;
Node_op_IndexRef : RNode_op_IndexRef;
inlenght : integer;
datavar : longint;
BEGIN
{ ***************************************************
**** S¢g efter leafblokken til at indsætte i ****
*************************************************** }
datavar := currentplace_in_ndx;
inlenght := BYTE(incoming[0]);
currentblocknumber := controlblock.ControlRoot;
read_block(ver,block, controlblock.ControlRoot);
Stack_up_count := 1;
FILLCHAR(Stack_up, SIZEOF (Stackarray), #0);
Stack_up[Stack_up_count] := controlblock.ControlRoot;
difference := -1;
Count := 0;
WHILE indexblock.IndexFirst <> - 1 DO
BEGIN
difference := - 1;
WHILE ( Count < indexblock.IndexCount ) AND (difference < 0) DO
BEGIN
difference := CompAddress (block[indexblock.IndexRef[Count].IndexOfs],incoming[1],
CHR(indexblock.IndexRef[Count].IndexLen),incoming[0]);
IF difference = 0 THEN
BEGIN { If K = 0 - we found the address ERROR }
insert_btree := false;
exit;
END
ELSE
IF difference < 0 THEN INC (Count); { move to right (i.e. Increment count) until difference >= 0 }
END;
IF Count = 0 THEN currentblocknumber := indexblock.IndexFirst
ELSE currentblocknumber := indexblock.IndexRef[Count-1].IndexPtr;
INC (Stack_up_count);
Stack_up [Stack_up_count] := currentblocknumber;
read_block (ver,block, currentblocknumber);
count := 0;
difference := - 1;
END;
{ *************************************************************************
**** Vi har fundet leafblokken og skal nu til at sætte noden i den ****
************************************************************************* }
Count := 0;
difference := -1;
IF ((((leafblock.indexcount+1) * 8) + 16) < (leafblock.IndexStr - inlenght)) AND (leafblock.IndexCount < 49) THEN
BEGIN
{ *******************************************************
**** Leafblokken er ikke fuld og noden indsættes ****
******************************************************* }
WHILE ( Count < leafblock.IndexCount ) AND (difference < 0) DO
BEGIN { Find ud af hvor noden skal indsættes, resultat i count }
difference := CompAddress(block[leafblock.LeafRef[Count].KeyOfs],incoming[1],
CHR(leafblock.LeafRef[Count].KeyLen),incoming[0]);
IF difference = 0 THEN
BEGIN { If K = 0 - we found the address ERROR }
insert_btree := false;
exit;
END
ELSE
IF difference < 0 THEN INC (Count); { move to right (i.e. Increment count) until difference >= 0 }
END; { Vi har nu fundet stedet hvor vi skal indsætte noden }
INC (leafblock.IndexCount);
FOR tempcounter := leafblock.IndexCount-1 DOWNTO Count+1 DO
BEGIN
leafblock.LeafRef [tempcounter] := leafblock.LeafRef [tempcounter - 1]
END;
leafblock.LeafRef [Count] .KeyOfs := leafblock.IndexStr - inlenght;
leafblock.LeafRef [Count] .KeyLen := inlenght;
leafblock.LeafRef [Count] .KeyVal := Datavar;
MOVE(incoming[1],block[leafblock.IndexStr-inlenght],inlenght);
leafblock.IndexStr := leafblock.IndexStr - inlenght;
write_block(ver,block,currentblocknumber);
END
ELSE
{ **********************************************************************
**** Leafblokken er fuld og der skal splittes til to leafblokke ****
********************************************************************** }
BEGIN
WHILE ( Count < leafblock.IndexCount ) AND (difference < 0) DO
BEGIN { Find ud af hvor noden skal indsættes, resultat i count }
difference := CompAddress (block [leafblock.LeafRef [Count] .KeyOfs], incoming [1],
CHR (leafblock.LeafRef [Count] .KeyLen),incoming[0] );
IF difference = 0 THEN
BEGIN { If K = 0 - we found the address ERROR }
insert_btree := false;
exit;
END
ELSE
IF difference < 0 THEN INC (Count); { move to right (i.e. Increment count) until difference >= 0 }
END; { Vi har nu fundet stedet hvor vi skal indsætte noden }
FILLCHAR (bigblock, SIZEOF (bblock), #0);
bigleafblock.IndexStr := 1023;
bigleafblock.IndexFirst := leafblock.IndexFirst;
bigleafblock.IndexBLink := leafblock.IndexBLink;
bigleafblock.IndexFLink := leafblock.IndexFLink;
bigleafblock.indexcount := leafblock.indexcount+1;
tempcounter := 0;
while tempcounter <= (Count-1) DO
BEGIN
bigleafblock.LeafRef [tempcounter] .KeyOfs := bigleafblock.IndexStr - leafblock.LeafRef [tempcounter] .KeyLen;
bigleafblock.IndexStr := bigleafblock.IndexStr - leafblock.LeafRef [tempcounter] .KeyLen;
bigleafblock.LeafRef [tempcounter] .KeyLen := leafblock.LeafRef [tempcounter] .KeyLen;
bigleafblock.LeafRef [tempcounter] .KeyVal := leafblock.LeafRef [tempcounter] .KeyVal;
MOVE(block [leafblock.LeafRef [tempcounter] .KeyOfs], bigblock [bigleafblock.LeafRef [tempcounter] .KeyOfs],
bigleafblock.LeafRef [tempcounter] .KeyLen);
inc(tempcounter);
END;
bigleafblock.LeafRef [Count] .KeyOfs := bigleafblock.IndexStr - inlenght;
bigleafblock.LeafRef[Count].KeyLen := inlenght;
bigleafblock.LeafRef [Count] .KeyVal := Datavar;
MOVE (incoming [1], bigblock [bigleafblock.IndexStr - inlenght], inlenght);
bigleafblock.IndexStr := bigleafblock.IndexStr - inlenght;
FOR tempcounter := Count TO bigleafblock.IndexCount-2 DO
BEGIN
bigleafblock.LeafRef [tempcounter + 1] .KeyOfs := bigleafblock.IndexStr-leafblock.LeafRef[tempcounter].KeyLen;
bigleafblock.IndexStr := bigleafblock.IndexStr - leafblock.LeafRef [tempcounter] .KeyLen;
bigleafblock.LeafRef [tempcounter + 1] .KeyLen := leafblock.LeafRef [tempcounter] .KeyLen;
bigleafblock.LeafRef [tempcounter + 1] .KeyVal := leafblock.LeafRef [tempcounter] .KeyVal;
MOVE (block [leafblock.LeafRef [tempcounter] .KeyOfs], bigblock[bigleafblock.LeafRef[tempcounter+1].KeyOfs],
bigleafblock.LeafRef [tempcounter + 1] .KeyLen);
END;
FILLCHAR (newblock, SIZEOF (tblock), #0);
FILLCHAR (leafblock, SIZEOF (tblock), #0);
leafblock.IndexStr := 511;
NOde_up_KeyVal := bigleafblock.IndexCount - 6; { original 8}
FOR tempcounter := 0 TO NOde_up_KeyVal-2 DO
BEGIN
leafblock.LeafRef[tempcounter].KeyOfs := leafblock.IndexStr - bigleafblock.LeafRef[tempcounter].KeyLen;
leafblock.LeafRef[tempcounter].KeyLen := bigleafblock.LeafRef[tempcounter].KeyLen;
leafblock.LeafRef[tempcounter].KeyVal := bigleafblock.LeafRef[tempcounter].KeyVal;
MOVE(bigblock[bigleafblock.LeafRef[tempcounter].KeyOfs],block[leafblock.IndexStr -
leafblock.LeafRef [tempcounter] .KeyLen], leafblock.LeafRef [tempcounter] .KeyLen);
leafblock.IndexStr := leafblock.IndexStr - leafblock.LeafRef[tempcounter].KeyLen;
END;
leafblock.indexcount := NOde_up_KeyVal-1;
newleafblock.IndexStr := 511;
FOR tempcounter := NOde_up_KeyVal-1 TO bigleafblock.IndexCount-1 DO
BEGIN
newleafblock.LeafRef[tempcounter-(NOde_up_KeyVal-1)].KeyOfs := newleafblock.IndexStr
- bigleafblock.LeafRef[tempcounter].KeyLen;
newleafblock.LeafRef[tempcounter-(NOde_up_KeyVal-1)].KeyLen := bigleafblock.LeafRef[tempcounter].KeyLen;
newleafblock.LeafRef[tempcounter-(NOde_up_KeyVal-1)].KeyVal := bigleafblock.LeafRef[tempcounter].KeyVal;
MOVE(bigblock[bigleafblock.LeafRef[tempcounter].KeyOfs],newblock[newleafblock.LeafRef[tempcounter
-(NOde_up_KeyVal-1)].KeyOfs],bigleafblock.LeafRef[tempcounter].KeyLen);
newleafblock.IndexStr := newleafblock.IndexStr-newleafblock.LeafRef[tempcounter-(NOde_up_KeyVal-1)].KeyLen;
END;
newleafblock.indexcount := (bigleafblock.IndexCount - NOde_up_KeyVal)+1;
leafblock.IndexFirst := - 1;
INC (controlblock.ControlHiBlock);
controlblock.ControlHighLeaf := controlblock.controlhiblock +1;
leafblock.IndexBLink := bigleafblock.IndexBLink;
leafblock.IndexFLink := controlblock.ControlHiBlock;
newleafblock.IndexFirst := - 1;
newleafblock.IndexBLink := currentblocknumber;
newleafblock.IndexFLink := bigleafblock.IndexFLink;
write_block (ver,block, currentblocknumber);
IF newleafblock.IndexFLink <> 0 THEN
BEGIN
read_block (ver,Block, newleafblock.IndexFLink);
leafBlock.IndexBLink := controlblock.ControlHiBlock;
write_block (ver,Block, newleafblock.IndexFLink);
END;
write_block (ver,newblock, controlblock.ControlHiBlock);
Node_op_IndexRef.IndexLen := bigleafblock.LeafRef [NOde_up_KeyVal-1] .KeyLen;
Node_op_IndexRef.IndexData := bigleafblock.LeafRef [NOde_up_KeyVal-1] .KeyVal;
Node_op_IndexRef.IndexPtr := controlblock.ControlHiBlock;
node_op_indexref.node[0] := chr(Node_op_IndexRef.IndexLen);
MOVE(bigblock[bigleafblock.LeafRef[NOde_up_KeyVal-1].KeyOfs], Node_op_IndexRef.node[1],
Node_op_IndexRef.IndexLen);
{ **********************************************************************
**** Node_op_indexRef skal nu indsættes i indexblokkene ****
********************************************************************** }
Finish := FALSE;
REPEAT
IF Stack_up_count = 1 THEN
BEGIN
{ ****************************************************
**** Der oprettes en ny root i træ'et ****
**************************************************** }
FILLCHAR(newblock,SIZEOF(newblock),#0);
newindexblock.IndexFirst := currentblocknumber;
newindexblock.IndexBLink := 0;
newindexblock.IndexFLink := 0;
newindexblock.IndexCount := 1;
newindexblock.IndexStr := 511;
newindexblock.IndexRef[0].IndexLen := Node_op_IndexRef.IndexLen;
newindexblock.IndexRef[0].IndexData := Node_op_IndexRef.IndexData;
newindexblock.IndexRef[0].IndexPtr := Node_op_IndexRef.IndexPtr;
newindexblock.IndexRef[0].IndexOfs := newindexblock.IndexStr - newindexblock.IndexRef[0].IndexLen;
newindexblock.IndexStr := newindexblock.IndexStr - Node_op_indexref.indexlen;
MOVE(Node_op_IndexRef.node[1],newblock[newindexblock.IndexRef[0].IndexOfs],
Node_op_IndexRef.IndexLen);
INC (controlblock.ControlHiBlock);
controlblock.ControlRoot := controlblock.ControlHiBlock;
INC (controlblock.ControlLevels);
write_block (ver,newblock, controlblock.ControlHiBlock);
Finish := TRUE;
END
ELSE
BEGIN
DEC (Stack_up_count);
read_block (ver,block, Stack_up[Stack_up_count]);
IF ((((indexblock.indexcount+1)*12)+16) < (indexblock.IndexStr - inlenght))
AND (indexblock.IndexCount <= 49) THEN
BEGIN { indexblokken er ikke fuld og noden indsættes }
{ ********************************************************
**** indexblokken er ikke fuld og noden indsættes ****
******************************************************** }
Count := 0;
difference := -1;
WHILE ( Count < indexblock.IndexCount ) AND (difference < 0) DO
BEGIN { Find ud af hvor noden skal indsættes, resultat i count }
difference := CompAddress(block[indexblock.IndexRef[Count].IndexOfs],Node_op_IndexRef.node[1],
CHR (indexblock.IndexRef[Count].IndexLen),Node_op_IndexRef.node[0]);
IF difference = 0 THEN
BEGIN { If K = 0 - we found the address ERROR }
insert_btree := false;
exit;
END
ELSE
IF difference < 0 THEN INC (Count); { move to right (i.e. Increment count) until difference >= 0 }
END; { Vi har nu fundet stedet hvor vi skal indsætte noden }
INC (indexblock.IndexCount);
FOR tempcounter := indexblock.IndexCount-1 DOWNTO Count+1 DO
BEGIN
indexblock.IndexRef [tempcounter] := indexblock.IndexRef [tempcounter - 1]
END;
{ IF count <> 0 Then
Begin}
indexblock.IndexRef [Count] .IndexOfs := indexblock.IndexStr - Node_op_indexref.indexlen;
indexblock.IndexRef [Count] .IndexLen := Node_op_indexref.indexlen;
indexblock.IndexRef [Count] .IndexData := Node_op_indexref.indexdata;
indexblock.IndexRef [Count] .IndexPtr := Node_op_indexref.indexPtr;
MOVE (Node_op_IndexRef.node[1],block[indexblock.IndexStr-Node_op_indexref.indexlen],
Node_op_IndexRef.IndexLen);
indexblock.IndexStr := indexblock.IndexStr-Node_op_indexref.indexlen;
{ End
Else
Begin
indexblock.IndexRef[Count].IndexPtr := indexblock.indexfirst;
indexblock.IndexRef [Count] .IndexOfs := indexblock.IndexStr - Node_op_indexref.indexlen;
indexblock.IndexRef [Count] .IndexLen := Node_op_indexref.indexlen;
indexblock.IndexRef [Count] .IndexData := Node_op_indexref.indexdata;
indexblock.Indexfirst := Node_op_indexref.indexPtr;
MOVE (Node_op_IndexRef.node[1],block[indexblock.IndexStr-Node_op_indexref.indexlen],
Node_op_IndexRef.IndexLen);
indexblock.IndexStr := indexblock.IndexStr - Node_op_indexref.indexlen;
End; }
write_block (ver,block, Stack_up [Stack_up_count]);
Finish := TRUE;
END
ELSE
BEGIN
{ ************************************************************************
**** indexblokken er fuld og der skal splittes til to indexblokke ****
************************************************************************ }
Count := 0;
difference := -1;
WHILE ( Count < indexblock.IndexCount ) AND (difference < 0) DO
BEGIN { Find ud af hvor noden skal indsættes, resultat i count }
difference := CompAddress(block[indexblock.IndexRef[Count].IndexOfs],Node_op_IndexRef.node[1],
CHR(indexblock.IndexRef[Count].IndexLen),Node_op_IndexRef.node[0]);
IF difference = 0 THEN
BEGIN { If K = 0 - we found the address ERROR }
insert_btree := false;
exit;
END
ELSE
IF difference < 0 THEN INC (Count); { move to right (i.e. Increment count) until difference >= 0 }
END; { Vi har nu fundet stedet hvor vi skal indsætte noden }
FILLCHAR(bigblock,SIZEOF(bblock),#0);
bigindexblock.IndexStr := 1023;
bigindexblock.IndexFirst := indexblock.IndexFirst;
bigindexblock.IndexBLink := indexblock.IndexBLink;
bigindexblock.IndexFLink := indexblock.IndexFLink;
bigindexblock.IndexCount := indexblock.IndexCount+1;
tempcounter := 0;
while tempcounter <= (Count-1) DO
BEGIN
bigindexblock.IndexRef[tempcounter].IndexOfs :=
bigindexblock.IndexStr-indexblock.IndexRef[tempcounter].IndexLen;
bigindexblock.IndexStr := bigindexblock.IndexStr - indexblock.IndexRef[tempcounter].IndexLen;
bigindexblock.IndexRef[tempcounter].IndexLen := indexblock.IndexRef[tempcounter].IndexLen;
bigindexblock.IndexRef[tempcounter].IndexData := indexblock.IndexRef[tempcounter].IndexData;
bigindexblock.IndexRef[tempcounter].IndexPtr := indexblock.IndexRef[tempcounter].IndexPtr;
MOVE (block [indexblock.IndexRef [tempcounter] .IndexOfs],
bigblock [bigindexblock.IndexRef [tempcounter]
.IndexOfs], bigindexblock.IndexRef [tempcounter] .IndexLen);
inc(tempcounter);
END;
bigindexblock.IndexRef[Count].IndexOfs := bigindexblock.IndexStr - Node_op_indexref.indexlen;
bigindexblock.IndexRef[Count].IndexLen := Node_op_indexref.indexlen;
bigindexblock.IndexRef[Count].IndexData := Node_op_indexref.indexdata;
bigindexblock.IndexRef[Count].IndexPtr := Node_op_indexref.indexPtr;
MOVE (Node_op_IndexRef.node[1],bigblock[bigindexblock.IndexStr-Node_op_IndexRef.IndexLen],
Node_op_IndexRef.IndexLen);
bigindexblock.IndexStr := bigindexblock.IndexStr - Node_op_indexref.indexlen;
FOR tempcounter := Count TO bigindexblock.IndexCount -2 DO
BEGIN
bigindexblock.IndexRef[tempcounter+1].IndexOfs := bigindexblock.IndexStr
-indexblock.IndexRef[tempcounter].IndexLen;
bigindexblock.IndexStr := bigindexblock.IndexStr-indexblock.IndexRef[tempcounter].IndexLen;
bigindexblock.IndexRef[tempcounter+1].IndexLen := indexblock.IndexRef[tempcounter].IndexLen;
bigindexblock.indexref[tempcounter+1].indexptr := indexblock.IndexRef[tempcounter].Indexptr;
bigindexblock.IndexRef[tempcounter+1].IndexData := indexblock.IndexRef[tempcounter].IndexData;
MOVE (block[indexblock.IndexRef[tempcounter].IndexOfs],
bigblock[bigindexblock.IndexRef[tempcounter+1].IndexOfs],
bigindexblock.IndexRef[tempcounter+1].IndexLen);
END;
FILLCHAR(newblock,SIZEOF(tblock),#0);
FILLCHAR(indexblock,SIZEOF(tblock),#0);
indexblock.IndexStr:=511;
node_up_keyval := bigindexblock.IndexCount -8;
indexblock.indexfirst := bigindexblock.indexfirst;
FOR tempcounter := 0 TO node_up_keyval-2 DO
BEGIN
indexblock.IndexRef[tempcounter].IndexOfs := indexblock.IndexStr
- bigindexblock.IndexRef[tempcounter].IndexLen;
indexblock.IndexRef[tempcounter].IndexLen := bigindexblock.IndexRef[tempcounter].IndexLen;
indexblock.IndexRef[tempcounter].IndexData := bigindexblock.IndexRef[tempcounter].IndexData;
indexblock.IndexRef[tempcounter].IndexPtr := bigindexblock.IndexRef[tempcounter].IndexPtr;
MOVE (bigblock[bigindexblock.IndexRef[tempcounter].IndexOfs],
block[indexblock.IndexRef[tempcounter].IndexOfs],indexblock.IndexRef[tempcounter].IndexLen);
indexblock.IndexStr := indexblock.IndexStr - indexblock.IndexRef[tempcounter].IndexLen;
END;
indexblock.indexcount := node_up_keyval-1;
newindexblock.IndexStr:=511;
newindexblock.indexfirst := bigindexblock.indexRef[NOde_up_KeyVal-1].indexptr;
FOR tempcounter := node_up_keyval TO bigindexblock.IndexCount-1 DO
BEGIN
newindexblock.IndexRef[tempcounter-node_up_keyval].IndexOfs := newindexblock.IndexStr
- bigindexblock.IndexRef[tempcounter].IndexLen;
newindexblock.IndexRef[tempcounter-node_up_keyval].IndexLen
:= bigindexblock.IndexRef[tempcounter].IndexLen;
newindexblock.IndexRef[tempcounter-node_up_keyval].IndexData
:= bigindexblock.IndexRef[tempcounter].IndexData;
newindexblock.IndexRef[tempcounter-node_up_keyval].IndexPtr
:= bigindexblock.IndexRef[tempcounter].IndexPtr;
MOVE(bigblock[bigindexblock.IndexRef[tempcounter].IndexOfs],
newblock[newindexblock.IndexRef[tempcounter-node_up_keyval].IndexOfs],
bigindexblock.IndexRef[tempcounter].IndexLen);
newindexblock.IndexStr := newindexblock.IndexStr-
newindexblock.IndexRef[tempcounter-node_up_keyval].IndexLen;
END;
newindexblock.indexcount := bigindexblock.indexcount - node_up_keyval;
currentblocknumber := Stack_up[Stack_up_count];
INC (controlblock.ControlHiBlock);
indexblock.IndexBLink := bigindexblock.IndexBLink;
indexblock.IndexFLink := controlblock.ControlHiBlock;
newindexblock.IndexBLink := currentblocknumber;
newindexblock.IndexFLink := bigindexblock.IndexFLink;
write_block (ver,block, currentblocknumber);
IF newindexblock.IndexFLink <> 0 THEN
BEGIN
read_block (ver,Block, newindexblock.IndexFLink);
indexBlock.IndexBLink := controlblock.ControlHiBlock;
write_block (ver,Block, newindexblock.IndexFLink);
END;
write_block(ver,newblock, controlblock.ControlHiBlock);
Node_op_IndexRef.IndexLen := bigindexblock.indexRef[NOde_up_KeyVal-1].indexLen;
Node_op_IndexRef.IndexData := bigindexblock.indexRef[NOde_up_KeyVal-1].indexdata;
Node_op_IndexRef.IndexPtr := controlblock.ControlHiBlock;
node_op_indexref.node[0] := chr(Node_op_IndexRef.IndexLen);
MOVE(bigblock[bigindexblock.indexRef[NOde_up_KeyVal-1].indexOfs],Node_op_IndexRef.node[1],
Node_op_IndexRef.IndexLen);
END;
END;
UNTIL Finish;
End;
insert_btree := true;
END;
BEGIN { write nodex.dat og nodex.ndx evt sysop.ndx}
packline :='';
packline := oursystemname + oursysop + ourmiscinfo;
packline := pack(packline);
with realdat do
begin
zone := curadr.zone;
net := curadr.net;
node := curadr.node;
point := curadr.point;
callcost := ourcost;
msgfee := 0;
nodeflags := 0;
IF IsHost THEN nodeflags:=nodeflags OR 2
ELSE
IF IsHub THEN nodeflags:=nodeflags OR 1
ELSE
IF IsRegion THEN nodeflags:=nodeflags OR 4;
IF IsCrash THEN nodeflags:=nodeflags OR 16;
IF IsPoint THEN NodeFlags:=NodeFlags Or 4096;
modemtype := ourmodemtype;
phonelen := length(ourphonenumber);
passwordlen := 0;
bnamelen := length(oursystemname);
snamelen := length(oursysop);
cnamelen := length(ourmiscinfo);
packlen := length(packline);
baud := curbaudrate div 300;
end;
addressline := makeaddress(curadr.zone,curadr.net,curadr.node,curadr.point);
if insert_btree(v7,addressline) then
begin
f1.Write(realdat,22);
f1.write(ourphonenumber[1],realdat.phonelen);
f1.Write(packline[1],realdat.packlen);
currentplace_in_ndx := currentplace_in_ndx + 22 + realdat.packlen+realdat.phonelen;
end;
{
if sysopindex then
begin
if insert_btree(v7,addressline) then
begin
end;
end;
}
END;
PROCEDURE GetNodeListLineInfo;
VAR
ss : STRING;
Num,
test,i : Integer;
w : SmallWord;
BEGIN
ss:=StUpCase(NextWord(',',s));
IsCrash:=False;
IsRegion:=(ss='REGION');
IsHost:=(ss='HOST');
IsDown:=(ss='DOWN');
IsHold:=(ss='HOLD');
IsZone:=(ss='ZONE');
IsHub:=(ss='HUB');
IsPvt:=(ss='PVT');
IsPoint:=(ss='POINT');
ss:=NextWord(',',s);
VAL(ss,Num,test);
IF IsPoint THEN
CurAdr.Point:=Num
ELSE
IF IsZone THEN
BEGIN
DoingService:=TRUE;
CurAdr.Zone:=Num;
CurAdr.Net:=Num;
CurAdr.Node:=0;
CurAdr.Point:=0;
HostPhone:='';
END ELSE
IF IsRegion OR IsHost {OR DoingService} THEN
BEGIN
DoingService:=False;
CurAdr.Net:=Num;
CurAdr.Node:=0;
END ELSE
CurAdr.Node:=Num;
OurSystemName:=NextWord(',',s);
Replace(OurSystemName,'_',' ',0);
IF IsDown THEN OurSystemName:='<'+OurSystemName;
OurMiscInfo:=NextWord(',',s);
Replace(OurMiscInfo,'_',' ',0);
OurSysOp:=NextWord(',',s);
Replace(OurSysOp,'_',' ',0);
IF OurSystemName=' ' THEN OurSystemName:=OurSysOp;
OurPhoneNumber:=NextWord(',',s);
IF IsHost THEN HostPhone:=OurPhoneNumber;
IF IsDown OR IsHold OR IsPvt THEN OurPhoneNumber:=HostPhone;
IF Not IsPoint THEN BossPhone:=OurPhoneNumber;
IF StUpCase(OurPhoneNumber)='-UNPUBLISHED-' THEN
IF IsPoint THEN OurPhoneNumber:=BossPhone ELSE OurPhoneNumber:=HostPhone;
IF NOT (Cfg.NodelistTyp IN [QBBSNodelistType, SBBSNodeListType, RANodeListType]) THEN
BEGIN
OurCost:=FindCost(OurPhoneNumber);
IF NOT IsOurAddress(CurAdr) THEN OurPhoneNumber:=PhoneTranslation(OurPhoneNumber);
END;
ss:=NextWord(',',s);
VAL(ss,CurBaudRate,Test);
ss:=StUpCase(s) ;
IF NOT (Cfg.NodelistTyp IN [QBBSNodelistType, SBBSNodeListType, RANodeListType]) THEN
GetSpecialModemInfo(StUpCase(s), OurModemType, w);
REPEAT
ss:=StUpCase(NextWord(',',s));
IF ss='CM' THEN IsCrash:=True;
UNTIL (s='') OR (Length(s)<2);
END;
FUNCTION CheckAddress(CONST Adr: TFidoAddress; CONST AdrTab: SendToTabType): Boolean;
VAR
Ok : Boolean;
i : Byte;
BEGIN
Ok:=False; i:=1;
WHILE Not Ok And (i<=50) And (AdrTab[i].Zone<>-2) DO
BEGIN
IF ((AdrTab[i].Zone=-1) Or (AdrTab[i].Zone=Adr.Zone)) And
((AdrTab[i].Net=-1) Or (AdrTab[i].Net=Adr.Net)) And
((AdrTab[i].Node=-1) Or (AdrTab[i].Node=Adr.Node)) THEN
Ok:=True
ELSE
Inc(i);
END;
CheckAddress:=Ok;
END;
BEGIN
IF First THEN
BEGIN
First:=False;
IF Cfg.NodeListTyp=Version7 THEN { Her indsættes de f¢rste to records i .ndx filen BK'94}
BEGIN
FILLCHAR(controlblock,512,#0);
currentplace_in_ndx := 0;
controlblock.ControlBlockSize := 512;
controlblock.ControlRoot := 1;
controlblock.ControlHiBlock := 1;
controlblock.ControlLowLeaf := 1;
controlblock.ControlHighLeaf := 1;
controlblock.ControlFree := 0;
controlblock.ControlLevels := 1;
controlblock.ControlParity := 0;
v7.seta(0,0,controlblock);
FILLCHAR(block,512,#0);
leafblock.IndexFirst := -1;
leafblock.IndexBLink := 0;
leafblock.IndexFLink := 0;
leafblock.IndexCount := 0;
leafblock.IndexStr := 511;
v7.seta(1,0,leafblock);
END;
END;
OldSLength:=Length(s);
IF s<>'' THEN
BEGIN
ch:=s[1];
IF (ch<>';') AND (ch<>' ') THEN
BEGIN
s:=s+',';
GetNodeListLineInfo;
IF IsZone OR IsHost THEN NetTitle:=OurSystemName;
IF (IsZone) Or (CheckAddress(CurAdr,InclTab) And Not CheckAddress(CurAdr,ExclTab)) THEN
BEGIN
IF Cfg.NLCompiler.UseFidoUserLst THEN
BEGIN
s:=OurSysOp;
i:=WordCount(s,[' ']);
ss:=ExtractWord(i,s,[' ']);
dec(s[0],Length(ss)+1);
if i>1 then ss:=ss+', '+s;
s:=Address2Str(CurAdr);
ss:=CPad(ss,60-Length(s))+s;
FidoUser.SetA(FidoUserNum,0,ss);
INC(FidoUserNum);
END;
CASE Cfg.NodeListTyp OF
RANodeListType,
SBBSNodeListType,
QBBSNodeListType : IF IsZone OR IsHost OR IsRegion THEN QBBSNode;
NewNodeListType : NewNode;
Version7 : V7Node;
END;
END;
IF Nettitle<>OldNettitle THEN
BEGIN
s:='('+Long2Str(CurAdr.Zone)+':'+Long2Str(CurAdr.Net)+'/*) "'+nettitle+'"';
s:=CPad(s,59);
Temp^.wFastWrite(s,WhereY,1,Cfg.Color[2].highlightcolor);
OldNettitle:=Nettitle;
END;
END;
END;
INC(CurNlPos,LongInt(OldSLength+2));
END;
FUNCTION SortFidoUser: Boolean;
VAR
Escaped : Boolean;
procedure QuickSort(L, R : Word);
{-Non-recursive QuickSort per N. Wirth's "Algorithms and Data Structures"}
const
StackSize = 20;
type
Stack = array[1..StackSize] of Word;
var
Lstack : Stack; {Pending partitions, left edge}
Rstack : Stack; {Pending partitions, right edge}
StackP : Integer; {Stack pointer}
Pl : Word; {Left edge within partition}
Pr : Word; {Right edge within partition}
StrPl, StrPr, Pivot : S62;
begin
{Initialize the stack}
StackP := 1;
Lstack[1] := L;
Rstack[1] := R;
Write('>>');
{Repeatedly take top partition from stack}
repeat
{Pop the stack}
L := Lstack[StackP];
R := Rstack[StackP];
Dec(StackP);
Write(#8'<'#8);
{Sort current partition}
repeat
{Load the pivot element}
FidoUser.RetA(L+Random(R-L), 0, Pivot);
Pl := L;
Pr := R;
{Swap items in sort order around the pivot index}
repeat
FidoUser.RetA(Pl, 0, StrPl);
while StrPl<Pivot do
begin
Inc(Pl);
FidoUser.RetA(Pl, 0, StrPl);
end;
FidoUser.RetA(Pr, 0, StrPr);
while StrPr>Pivot do
begin
Dec(Pr);
FidoUser.RetA(Pr, 0, StrPr);
end;
if Pl <= Pr then
begin
if Pl <> Pr then
begin
{Swap the two elements}
FidoUser.SetA(Pl, 0, StrPr);
FidoUser.SetA(Pr, 0, StrPl);
end;
if Pl < 65535 then Inc(Pl);
if Pr > 0 then Dec(Pr);
end;
Escaped:=GotEsc;
IF Escaped THEN Exit;
until Pl > Pr;
{Decide which partition to sort next}
if (Pr-L) < (R-Pl) then
begin
{Left partition is bigger}
if Pl < R then
begin
{Stack the request for sorting right partition}
Inc(StackP);
Lstack[StackP] := Pl;
Rstack[StackP] := R;
Write('>');
end;
{Continue sorting left partition}
R := Pr;
end else
begin
{Right partition is bigger}
if L < Pr then
begin
{Stack the request for sorting left partition}
Inc(StackP);
Lstack[StackP] := L;
Rstack[StackP] := Pr;
Write('>');
end;
{Continue sorting right partition}
L := Pl;
end;
until L >= R;
until StackP <= 0;
Write(#8'<'#8);
end;
BEGIN
Escaped:=False;
Dec(FidoUserNum);
QuickSort(0,FidoUserNum);
SortFidoUser:=NOT Escaped;
END;
PROCEDURE DecodeAdr(VAR AdrTab: SendToTabType; AdrStr: SendToType) ;
VAR
i,j,x : Byte;
TmpStr : s20;
Err : Integer;
BEGIN
FillChar(AdrTab, SizeOf(AdrTab), 0);
i:=1;
FOR j:=1 TO 2 DO
BEGIN
WHILE AdrStr[j]<>'' DO
BEGIN
x:=Pos(' ',AdrStr[j]);
IF x>0 THEN
BEGIN
TmpStr:=Copy(AdrStr[j],1,x-1);
Delete(AdrStr[j],1,x) ;
END ELSE
BEGIN
TmpStr:=AdrStr[j];
AdrStr[j]:='';
END;
x:=Pos(':',TmpStr);
IF StUpCase(Copy(TmpStr,1,x-1))='ALL' THEN
AdrTab[i].Zone:=-1
ELSE
Val(Copy(TmpStr,1,x-1),AdrTab[i].Zone,Err);
Delete(TmpStr,1,x);
x:=Pos('/',TmpStr);
IF StUpCase(Copy(TmpStr,1,x-1))='ALL' THEN
AdrTab[i].Net:=-1
ELSE
Val(Copy(TmpStr,1,x-1),AdrTab[i].Net,Err);
Delete(TmpStr,1,x);
IF StUpCase(TmpStr)='ALL' THEN
AdrTab[i].Node:=-1
ELSE
Val(TmpStr,AdrTab[i].Node,Err);
Inc(i)
END;
END;
AdrTab[i].Zone:=-2;
END;
BEGIN
ReadTranslationTable(False);
ReadCostTable(False);
IF Cfg.NLCompiler.UseFidoUserLst THEN
BEGIN
FidoUser.Init(50000, 1, 62, '$FIDOUSR.SRT', Max64k((MaxAvail-2048) DIV 3), lDeleteFile, DefaultPriority);
FidoUserNum:=0;
END;
MaxBufSize:=Max64k((MaxAvail-1024) DIV 3);
IF Cfg.NodelistTyp = Version7 Then
Begin
v7.Init(3000, 1, 512, '$v7nl.SRT', Max64k((MaxAvail-2048) DIV 3), lDeleteFile, DefaultPriority);
End;
IF NOT (Cfg.NodelistTyp IN [QBBSNodeListType,SBBSNodelistType,RANodeListType]) THEN
f1.Init(MakeTaskFileName(Cfg.NodeList+'POP_NL.DAT'), SCreate, Max64k((MaxAvail-MaxBufSize) DIV 10 * 8));
f2.Init(MakeTaskFileName(Cfg.NodeList+'POP_NL.IDX'), SCreate, Max64k(MaxAvail-MaxBufSize-2048));
FileNum:=0;
OldZone:=-1;
OldNettitle:='';
NetTitle:='';
IF Cfg.NodeListTyp=NewNodeListType THEN
BEGIN
FillChar(V6, SizeOf(V6), 0);
V6.NetNumber:=-1;
V6.NodeNumber:=6;
Str2AsciiZ('Portal of Power',V6.SystemName,34);
V6I.Net:=-1;
V6I.Node:=6;
f1.Write(V6, SizeOf(V6));
f2.Write(V6I, SizeOf(V6I));
END;
FirstRec:=True; First:=True; DoingService:=True;
NodeListSegFile.Seek(0);
WHILE Not NodeListSegFile.EoF DO
BEGIN
NodeListSegFile.Read(NodeListSegRec,NoKeep,Wait);
IF FindOldNlName(OldNlName,Num) THEN
BEGIN
WriteLn('Compiling '+JustFileName(oldnlname));
f.Init(oldnlname, SOpenRead+ShareDenyNone, MaxBufSize);
DecodeAdr(InclTab,NodeListSegRec.Include) ;
IF InclTab[1].Zone=-2 THEN
BEGIN
InclTab[1].Zone:=-1;
InclTab[1].Net:=-1;
InclTab[1].Node:=-1;
InclTab[1].Point:=-1;
InclTab[2].Zone:=-2;
END;
DecodeAdr(ExclTab,NodeListSegRec.Exclude) ;
FillChar(CurAdr, SizeOf(CurAdr), 0);
CurAdr.Zone:=NodelistSegRec.DefaultZone;
IF FirstRec And (Cfg.NodeListTyp=NewNodeListType) THEN ProcessNodeListLine('');
IF Cfg.NodeListTyp IN [QBBSNodeListType,RANodeListType,SBBSNodeListType] THEN
AddFileNum(JustFileName(oldnlname),FirstRec);
HostPhone:='';
CurNLPos:=0;
WHILE NOT f.EoF DO
BEGIN
f.ReadLn(s);
ProcessNodeListLine(s);
END;
f.Done;
Temp^.wFastWrite(CharStr(' ',59),WhereY,1,Cfg.Color[2].TextColor);
END;
FirstRec:=False;
END;
WriteLn(#13#10,'Closing compiled nodelist...');
if (Cfg.NodeListTyp=Version7) then { Indsat BK '95 }
begin
f2.seek(512); { indsat BK'94 }
for v7num := 1 to controlblock.ControlHiBlock do
begin
v7.reta(v7num,0,tempblock);
f2.write(tempblock,controlblock.controlblocksize);
end;
v7.done;
f2.seek(0); { indsat BK'94 }
with controlblock do
ControlParity := ControlBlockSize XOR ControlRoot
XOR ControlHiBlock XOR ControlLowLeaf
XOR ControlHighLeaf XOR ControlFree
XOR ControlLevels;
f2.Write(controlblock,controlblock.controlblocksize); { indsat BK'94 }
end;
f2.Done;
IF Not (Cfg.NodeListTyp IN [RANodeListType,SBBSNodelistType,QBBSNodeListType]) THEN f1.Done;
OpenLockFile;
REPEAT
GiveUpTime;
UNTIL NetGrabFile(NetNLFile);
CASE Cfg.NodeListTyp OF
NewNodeListType : BEGIN
DeleteFile(Cfg.NodeList+'NODELIST.IDX');
DeleteFile(Cfg.NodeList+'NODELIST.DAT');
RenameFile(MakeTaskFileName(Cfg.NodeList+'POP_NL.IDX'),
Cfg.NodeList+'NODELIST.IDX');
RenameFile(MakeTaskFileName(Cfg.NodeList+'POP_NL.DAT'),
Cfg.NodeList+'NODELIST.DAT');
END;
SBBSNodeListType,
QBBSNodeListType,
RANodeListType : BEGIN
DeleteFile(Cfg.NodeList+ListExtension('NODEIDX.'));
RenameFile(MakeTaskFileName(Cfg.NodeList+'POP_NL.IDX'),
Cfg.NodeList+ListExtension('NODEIDX.'));
END;
Version7 : BEGIN
DeleteFile(Cfg.NodeList+'NODEX.NDX');
DeleteFile(Cfg.NodeList+'NODEX.DAT');
DeleteFile(Cfg.NodeList+'SYSOP.NDX');
RenameFile(MakeTaskFileName(Cfg.NodeList+'POP_NL.IDX'),
Cfg.NodeList+'NODEX.NDX');
RenameFile(MakeTaskFileName(Cfg.NodeList+'POP_NL.DAT'),
Cfg.NodeList+'NODEX.DAT');
END;
END;
NetReleaseFile(NetNLFile);
CloseLockFile;
SetToDoFlags(ICTDReReadNLIdx);
IF Cfg.NLCompiler.UseFidoUserLst THEN
BEGIN
Write('Sorting FIDOUSER.LST ');
IF SortFidoUser THEN
BEGIN
WriteLn(#13#10'Writing sorted FIDOUSER.LST');
IF FidoUserLst.Init(Cfg.NodeList+'FIDOUSER.LST', SCreate, Max64k(MaxAvail-1024)) THEN
BEGIN
FOR i:=0 TO FidoUserNum DO
BEGIN
FidoUser.RetA(i,0,s);
FidoUserLst.WriteLn(s);
END;
FidoUserLst.Done;
END ELSE
WriteLn('Error opening FIDOUSER.LST');
WriteLn(#13#10'Done');
END ELSE
WriteLn(#13#10'Sorting of FIDOUSER.LST aborted!');
FidoUser.Done;
END;
WaitForAction(10);
END;
BEGIN
{$IFNDEF PoPLite}
IF (Cfg.TaskType=2) AND (NOT Forced) THEN
BEGIN
RequestFunction(fsCompileNodelist);
EXIT;
END;
FillChar(Call, SizeOf(Call), 0);
IF Not SetInterCom(ICNLComp,Call,False) THEN Exit;
IF NodeListSegFile.Open(StartPath+PoPNLSegmentFileName,SizeOf(TNodeListSeg),False) THEN
BEGIN
FreeUpMemory;
MyWin(Temp,10,8,70,20,2,'NodeList Compiler',True);
IF MaxAvail>65536 THEN
BEGIN
IF NOT Cfg.NLCompiler.UseFidoUserLst OR (DriveFree(Ord(Cfg.Nodelist[1])-64)>2048000) THEN
BEGIN
FoundOne:=Forced;
WHILE Not NodeListSegFile.EoF DO
BEGIN
NodeListSegFile.Read(NodeListSegRec,NoKeep,Wait);
IF FindOldNlName(OldNlName, Num) AND (NodeListSegRec.DiffFileName<>'') AND ProcessNodeDiff THEN FoundOne:=True;
END;
IF FoundOne THEN ProcessNodeList;
END ELSE
AddLog('!','Not enough free disk space on drive '+Copy(Cfg.NodeList,1,2)+' to compile nodelist');
END ELSE
AddLog('!','Not enough memory to compile nodelist');
KillWindow(Temp);
InitialiseNodeList(Cfg.NodeList,Cfg.NodeListTyp);
NodeListSegFile.Close;
END;
{$ENDIF}
END;
END.